// Ptyxiaki.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

LinkedListPointer intVars;
LinkedListPointer dVars;
LinkedListPointer cVars;
LinkedListPointer bVars;
LinkedListPointer constants;
LinkedListPointer BindedWords;

process_inf proTable[40];
process_inf funTable[40];

int main(int argc, char *argv[])
{	
	char dieuthinsiInputFile[100],dieuthinsiOutFile[100],lineToProcess[100],processedLine[100];
	FILE *pseudokodikas,*cKodikas,*noTabsPseudokodikas,*noCommas;
	char t1[L_tmpnam_s],t2[L_tmpnam_s];   	//For temporary files later
	char tmp1[L_tmpnam_s+1],tmp2[L_tmpnam_s+1];
	char noCommasBuf[USHRT_MAX];
	int i,j,k;
	int numOfProcesses,numOfFuncs,funcsToPass;

	numOfProcesses=-1;
	numOfFuncs=-1;

	memset(noCommasBuf,'\0',USHRT_MAX-1);
	
	//Initialization of start of list pointers
	intVars=(LinkedListPointer)malloc(sizeof(LinkedListNode));
	dVars=(LinkedListPointer)malloc(sizeof(LinkedListNode));
	cVars=(LinkedListPointer)malloc(sizeof(LinkedListNode));
	bVars=(LinkedListPointer)malloc(sizeof(LinkedListNode));
	constants=(LinkedListPointer)malloc(sizeof(LinkedListNode));
	BindedWords=(LinkedListPointer)malloc(sizeof(LinkedListNode));			//Used for closed brackets check

	for (i=0;i<40;i++)
	{
		memset(proTable[i].name,'\0',40);
		memset(proTable[i].proto,'\0',100);
		proTable[i].vars=(LinkedListPointer)malloc(sizeof(LinkedListNode));
		createList(proTable[i].vars);
	}
	for (i=0;i<40;i++)
	{
		memset(funTable[i].name,'\0',40);
		memset(funTable[i].proto,'\0',100);
		funTable[i].vars=(LinkedListPointer)malloc(sizeof(LinkedListNode));
		createList(funTable[i].vars);
	}
	
	
	//Setting locale to greek for proper character encoding
	//printf ("Locale is: %s\n", setlocale(LC_ALL,"Greek") ) ;
	printf ("Locale is: %s\n", setlocale(LC_ALL,"Greek") ) ;
	//Initializaton of helping variables
    i=0;

	//Getting input/output file locations from argv
	strcpy(dieuthinsiInputFile,argv[1]);
	strcpy(dieuthinsiOutFile,argv[2]);

	//Getting temporary fle names
	
	tmpnam_s(t2,L_tmpnam_s);
	tmpnam_s(t1,L_tmpnam_s);
	
	strcpy(tmp1,".");
	strcat(tmp1,t1);
	strcpy(tmp2,".");
	strcat(tmp2,t2);
	//Opening input/output and temp files with proper modes
	pseudokodikas=fopen(dieuthinsiInputFile,"r");
	cKodikas=fopen(dieuthinsiOutFile,"w");
	noTabsPseudokodikas=fopen(/*"C:/Users/Aris/New.txt"*/tmp1,"w");
	fclose(cKodikas);
	putIncludes(dieuthinsiOutFile);

	//Creating lists for variable and binded word checking
	createList(intVars);
	createList(dVars);
	createList(cVars);
	createList(bVars);
	createList(constants);
	createList(BindedWords);
	
	/*Creating a temporary file with no left tabs in 
		it for easier processing*/
	while (!feof(pseudokodikas))
	{
		char *token,*temp;

		fgets(lineToProcess,sizeof(lineToProcess),pseudokodikas);
		token=strtok_s(lineToProcess," \t\r",&temp);
		i=0;
		while (token!=NULL)
		{
			if (i==0)
				fputs(token,noTabsPseudokodikas);
			else
				fprintf(noTabsPseudokodikas," %s",token);
			i++;
			token=strtok_s(NULL," \t\r",&temp);
		}
	}
	//Closing noTabsPseudokodikas to reopen in reading mode
	fclose(noTabsPseudokodikas);		

	noTabsPseudokodikas=fopen(/*"C:/Users/Aris/New.txt"*/tmp1,"r");
	noCommas=fopen(/*"C:/Users/Aris/New2.txt"*/tmp2,"w");
	while (!feof(noTabsPseudokodikas))
	{
		char *token,*temp;
		int i;
		fgets(lineToProcess,sizeof(lineToProcess),noTabsPseudokodikas);
		i=strlen(lineToProcess);
		token=strtok(lineToProcess,",");
		while (token!=NULL)
		{
			if (strlen(token)==i)
			{
				//fprintf(noCommas,"%s",token);
				strcat(noCommasBuf,token);
				break;
			}
			//fprintf(noCommas,"%s",token);
			strcat(noCommasBuf,token);
			printf("%s",token);
			token=strtok(NULL,",");
			if (token!=NULL)
				//fprintf(noCommas,", ",token);
				strcat(noCommasBuf,", ");
		}
	}
	int change;
	change=0;
	for (i=0; i<USHRT_MAX; i++)
	{
		
		if (noCommasBuf[i]=='\0')
			break;
		if (noCommasBuf[i]=='[')
			change=1;
		if (noCommasBuf[i]==']')
			change=0;
		if (noCommasBuf[i]==',' && change==1)
		{
			noCommasBuf[i]=']';
			noCommasBuf[i+1]='[';
		}
	}
	//fprintf(noCommas,"%s",noCommasBuf);
	i=0;
	do
	{
		if (noCommasBuf[i]=='<' && noCommasBuf[i+1]=='-')
		{
			fputs(" <- ",noCommas);
			i++;
		}
		else if (noCommasBuf[i]=='<' && noCommasBuf[i+1]=='>')
		{
			fputs(" <> ",noCommas);
			i++;
		}
		else if (noCommasBuf[i]=='='&& noCommasBuf[i+1]=='<')
		{
			fputs(" =< ",noCommas);
			i++;
		}
		else if (noCommasBuf[i]=='>'&& noCommasBuf[i+1]=='=')
		{
			fputs(" >= ",noCommas);
			i++;
		}
		else if (noCommasBuf[i]=='<')
			fputs(" < ",noCommas);
		else if (noCommasBuf[i]=='>')
			fputs(" > ",noCommas);
		else if (noCommasBuf[i]=='=')
			fputs(" = ",noCommas);
		else if (noCommasBuf[i]=='(')
			fputs(" ( ",noCommas);
		else if (noCommasBuf[i]==')')
			fputs(" ) ",noCommas);
		else if (noCommasBuf[i]=='+')
			fputs(" + ",noCommas);
		else if (noCommasBuf[i]=='-')
			fputs(" - ",noCommas);
		else if (noCommasBuf[i]=='/')
			fputs(" / ",noCommas);
		else if (noCommasBuf[i]=='*')
			fputs(" * ",noCommas);
		else if (noCommasBuf[i]==',')
			fputs(" , ",noCommas);
		else
			fputc(noCommasBuf[i],noCommas);
		i++;
	}while(noCommasBuf[i]!='\0');

	fclose(noTabsPseudokodikas);
	fclose(noCommas);
	//Check returning values of listisempty and closedforms
//	i=closedForms(BindedWords);
//	printf("list empty result=%d\n",i);

	
	declareConsts(/*"C:/Users/Aris/New.txt"*/tmp2,dieuthinsiOutFile);
	declareProcesses(/*"C:/Users/Aris/New2.txt"*/tmp2,dieuthinsiOutFile,&numOfProcesses);
	declareFunctions(/*"C:/Users/Aris/New2.txt"*/tmp2,dieuthinsiOutFile,&numOfFuncs);
	funcsToPass=numOfFuncs;
	declareVars(/*"C:/Users/Aris/New2.txt"*/tmp2,dieuthinsiOutFile/*,intVars,doubleVars,charVars,boolVars*/);
	translateBody(/*"C:/Users/Aris/New2.txt"*/tmp2,dieuthinsiOutFile/*,intVars,doubleVars,charVars,boolVars*/);
	if(numOfFuncs!=-1)
		translateFunctions(tmp2,dieuthinsiOutFile,&numOfFuncs);
	if(numOfProcesses!=-1)
		translateProcesses(tmp2,dieuthinsiOutFile,&numOfProcesses,funcsToPass);

	/*Closing files and emptying memory. 
		Also deletes list starting nodes*/
	remove(tmp1);
	remove(tmp2);
	fclose(pseudokodikas);
	free(intVars);
	free(dVars);
	free(cVars);
	free(bVars);
	free(constants);
	free(BindedWords);
	return 0;
}

